<template>
  <view class="paginated-list">
    <!-- 下拉刷新 -->
    <view v-if="enablePullRefresh">
      <slot name="pull-refresh" :refreshing="refreshing">
        <view class="refresh-container" v-if="refreshing">
          <text>刷新中...</text>
        </view>
      </slot>
    </view>
    
    <!-- 列表内容 -->
    <scroll-view 
      class="list-container"
	  scroll-y
      :refresher-enabled="enablePullRefresh"
      :refresher-triggered="refreshing"
      @refresherrefresh="handleRefresh"
      @scrolltolower="loadMore"
    >
      <slot :items="items" :loading="loading">
        <view v-for="(item, index) in items" :key="getKey(item, index)" class="list-item">
          <text>{{ item }}</text>
        </view>
      </slot>
      
      <!-- 加载状态 -->
      <view class="loading-state">
        <slot name="loading" :loading="loading" :noMore="noMore">
          <view v-if="loading" class="loading-more">
            <text>加载中...</text>
          </view>
          <view v-else-if="noMore" class="no-more">
            <text>没有更多数据了</text>
          </view>
        </slot>
      </view>
    </scroll-view>
    
    <!-- 错误提示 -->
    <view v-if="error" class="error-container">
      <slot name="error" :error="error" :retry="retry">
        <text>加载失败: {{ error.message }}</text>
        <button @click="retry">重试</button>
      </slot>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const props = defineProps({
  // 获取数据的函数，需要返回Promise
  fetchData: {
    type: Function,
    required: true
  },
  // 每页大小
  pageSize: {
    type: Number,
    default: 10
  },
  // 是否启用下拉刷新
  enablePullRefresh: {
    type: Boolean,
    default: true
  },
  // 自定义key生成函数
  getKey: {
    type: Function,
    default: (item, index) => index
  },
  // 是否自动加载第一页
  autoLoad: {
    type: Boolean,
    default: true
  }
})

const items = ref([])
const currentPage = ref(1)
const loading = ref(false)
const refreshing = ref(false)
const noMore = ref(false)
const error = ref(null)

// 加载数据
const loadData = async (isRefresh = false) => {
  if (loading.value || (noMore.value && !isRefresh)) return;
  
  try {
    error.value = null;
    loading.value = true;
    const pageToLoad = isRefresh ? 1 : currentPage.value;
	const response = await props.fetchData(pageToLoad, props.pageSize);
    const data = Array.isArray(response) ? response : response?.data || [];
    
    if (!Array.isArray(data)) {
      throw new Error("返回的数据不是数组");
    }
    
    if (isRefresh) {
      items.value = data;
      currentPage.value = 2;
      noMore.value = data.length < props.pageSize;
    } else {
      items.value = [...items.value, ...data];
      currentPage.value++;
      noMore.value = data.length < props.pageSize;
    }
  } catch (err) {
    error.value = err;
    console.error("加载数据失败:", err);
  } finally {
    loading.value = false;
    refreshing.value = false;
  }
}



// 加载更多
const loadMore = () => {
  if (!loading.value && !noMore.value) {
    loadData()
  }
}

// 刷新数据
const handleRefresh = () => {
  console.log("触发 handleRefresh，当前 refreshing:", refreshing.value);
  if (!refreshing.value) {
    refreshing.value = true;
    loadData(true).catch(() => {
      refreshing.value = false; // 确保即使出错也能重置
    });
  }
};

// 重试
const retry = () => {
  error.value = null
  loadData()
}

// 重置状态并重新加载
const reset = () => {
  items.value = []
  currentPage.value = 1
  noMore.value = false
  error.value = null
  loadData()
}

// 使用新数据重新加载列表
const reloadWithData = (newData) => {
  items.value = newData
  currentPage.value = 1
  noMore.value = newData.length < props.pageSize
  error.value = null
  loading.value = false
  refreshing.value = false
}

// 暴露方法给父组件
defineExpose({
  reset,
  refresh: () => loadData(true),
  reloadWithData
})

// 自动加载第一页
onMounted(() => {
  if (props.autoLoad) {
    loadData()
  }
})
</script>


<style scoped>
.paginated-list {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.list-container {
  flex: 1;
  height: 100%;
}

.refresh-container {
  padding: 20rpx;
  text-align: center;
  color: #999;
}

.loading-state {
  padding: 20rpx;
  text-align: center;
  color: #999;
}

.error-container {
  padding: 20rpx;
  text-align: center;
  color: #ff0000;
}

.list-item {
  padding: 20rpx;
  border-bottom: 1rpx solid #eee;
}

.no-more{
	margin-top: 60rpx;
	font-size: 24rpx;
}
</style>